package org.jsola.hr.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.jsola.admin.constant.AdminPermissionConstants;
import org.jsola.admin.constant.AminRightOprTypeEnum;
import org.jsola.admin.service.IAddedServiceOpenService;
import org.jsola.admin.service.IMenuService;
import org.jsola.admin.vo.AddedServiceListVO;
import org.jsola.admin.vo.AllPermissionVO;
import org.jsola.admin.vo.MenuVO;
import org.jsola.common.StrKit;
import org.jsola.core.entity.BaseDO;
import org.jsola.hr.constant.HrPermissionConstants;
import org.jsola.hr.entity.ChannelDO;
import org.jsola.hr.entity.EmpInfoDO;
import org.jsola.hr.provider.IAdminProviderService;
import org.jsola.hr.provider.IPermissionProviderService;
import org.jsola.hr.service.IChannelService;
import org.jsola.hr.service.IEmpInfoService;
import org.jsola.hr.service.IHrPermissionService;
import org.jsola.hr.vo.ChannelVO;
import org.jsola.permission.common.PermissionKit;
import org.jsola.permission.constant.PermissionConstants;
import org.jsola.permission.dao.IRightDAO;
import org.jsola.permission.entity.PermissionDO;
import org.jsola.permission.entity.RightDO;
import org.jsola.permission.service.IPermissionService;
import org.jsola.permission.service.IRightService;
import org.jsola.user.core.TokenUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static org.jsola.hr.constant.HrPermissionConstants.*;
import static org.jsola.hr.constant.HrPermissionConstants.HR_SUBJECT_TYPE;

/**
 * @author zhr
 */
@Service
@Slf4j
public class HrPermissionServiceImpl implements IHrPermissionService {

    @Autowired
    private IPermissionProviderService permissionProviderService;
    @Autowired
    private IRightDAO rightDAO;
    @Autowired
    private IAdminProviderService adminProviderService;
    @Autowired
    private IAddedServiceOpenService addedServiceOpenService;
    @Autowired
    private IEmpInfoService empInfoService;
    @Autowired
    private IChannelService channelService;

    @Override
    public boolean hasRight(String userId, String siteId, String subjectId, String subjectType) {
        return this.isAdmin(userId, siteId) || this.isSuperCompanyAdmin(userId, siteId) || permissionProviderService.hasRight(userId, siteId, subjectId, subjectType);
    }

    @Override
    public boolean hasRight(String userId, String siteId, String permissionString) {
        boolean result = this.isAdmin(userId, siteId);
        if (result) {
            return true;
        }
        boolean flag = permissionProviderService.hasRight(userId, siteId, permissionString);
        if (flag) {
            return true;
        }
        //替换subjectId为总公司id然后校验权限
        if (StrKit.isNotEmpty(permissionString) && permissionString.split(":").length == 4) {
            String temp = permissionString.substring(permissionString.lastIndexOf(":") + 1);
            permissionString = permissionString.replaceAll(temp, SUPER_COMPANY_ADMIN);
            return permissionProviderService.hasRight(userId, siteId, permissionString);
        }
        return false;
    }

    @Override
    public boolean hasAllRight(String userId, String siteId, String... permissionString) {
        return this.isAdmin(userId, siteId) || permissionProviderService.hasAllRight(userId, siteId, permissionString);
    }

    @Override
    public boolean hasAnyRight(String userId, String siteId, String... permissionString) {
        return this.isAdmin(userId, siteId) || permissionProviderService.hasAnyRight(userId, siteId, permissionString);
    }

    @Override
    public boolean hasObjRight(String userId, String siteId, String subjectId, String permissionString) {
        return this.isAdmin(userId, siteId) || permissionProviderService.hasObjRight(userId, siteId, subjectId, permissionString);
    }

    @Override
    public boolean hasObjAllRight(String userId, String siteId, String subjectId, String... permissionString) {
        return this.isAdmin(userId, siteId) || permissionProviderService.hasObjAllRight(userId, siteId, subjectId, permissionString);
    }

    @Override
    public boolean hasObjAnyRight(String userId, String siteId, String subjectId, String... permissionString) {
        return this.isAdmin(userId, siteId) || permissionProviderService.hasObjAnyRight(userId, siteId, subjectId, permissionString);
    }

    @Override
    public boolean isAdmin(String userId, String siteId) {
        return permissionProviderService.isAdmin(userId, siteId, HrPermissionConstants.HR_DEFAULT_SUBJECT_ID, HrPermissionConstants.HR_SUBJECT_TYPE)
                || permissionProviderService.isAdmin(userId, siteId, HrPermissionConstants.HR_DEFAULT_SUBJECT_ID, HrPermissionConstants.SYSTEM_SUBJECT_TYPE);
    }

    @Override
    public boolean isAdminValidaGroup(String userId, String siteId) {
        return permissionProviderService.isAdminValidaGroup(userId, siteId, HrPermissionConstants.HR_DEFAULT_SUBJECT_ID, HrPermissionConstants.HR_SUBJECT_TYPE)
                || permissionProviderService.isAdminValidaGroup(userId, siteId, HrPermissionConstants.HR_DEFAULT_SUBJECT_ID, HrPermissionConstants.SYSTEM_SUBJECT_TYPE);
    }

    @Override
    public boolean isSuperCompanyAdmin(String userId, String siteId) {
        return permissionProviderService.hasRight(userId, siteId, SUPER_COMPANY_ADMIN, COMPANY_SUBJECT_TYPE);
    }

    @Override
    public AllPermissionVO listUserPermission(String companyId, TokenUser tokenUser) {
        AllPermissionVO allPermissionVO = adminProviderService
                .getAllPermission(tokenUser.getUserId(), companyId, COMPANY_SUBJECT_TYPE, tokenUser.getSiteId());

        //管理员加载所有菜单和原子权限串
        if (isAdmin(tokenUser.getUserId(), tokenUser.getSiteId())) {
            List<String> subjectTypeList = new ArrayList<>();
            subjectTypeList.add(SYSTEM_SUBJECT_TYPE);
            subjectTypeList.add(HR_SUBJECT_TYPE);
            subjectTypeList.add(COMPANY_SUBJECT_TYPE);
            allPermissionVO.setMenuList(adminProviderService.getMenuList(subjectTypeList));

            //租户开通的增值服务
            List<AddedServiceListVO> addedServiceListVOS = addedServiceOpenService.selectServiceBySite(tokenUser.getSiteId());
            List<String> addedServiceSubjectType = addedServiceListVOS.stream().filter(AddedServiceListVO::getOpenStatus)
                    .map(AddedServiceListVO::getServiceCode).collect(Collectors.toList());

            List<PermissionDO> permissionList = new ArrayList<>();
            for (String addedService : addedServiceSubjectType) {
                List<PermissionDO> list = permissionProviderService.getPermissionList(addedService);
                permissionList.addAll(list);
            }

            //小程序管理端所有权限
            List<PermissionDO> xcxAdminPermissions = permissionProviderService.getPermissionList(XCX_ADMIN_SUBJECT_TYPE);
            permissionList.addAll(xcxAdminPermissions);

            //小程序甲方端所有权限
            List<PermissionDO> xcxJiafangPermissions = permissionProviderService.getPermissionList(XCX_JIAFANG_SUBJECT_TYPE);
            permissionList.addAll(xcxJiafangPermissions);

            // 操作端所有权限
            List<String> pmsStringList = allPermissionVO.getPermissionStringList();
            if (!CollectionUtils.isEmpty(pmsStringList)) {
                List<PermissionDO> companyPermissions = permissionProviderService.getPermissionList(COMPANY_SUBJECT_TYPE);
                companyPermissions.addAll(permissionList);
                pmsStringList.addAll(permissionProviderService.getPermissionStringList(companyPermissions));
            } else {
                allPermissionVO.setPermissionStringList(permissionProviderService.getPermissionStringList(permissionList));
            }
        }

        //如果是渠道并且不是公司管理员，加上管理端小程序所有权限
        List<String> userIds = permissionProviderService.selectHadRoleUserIdBySiteId(tokenUser);
        if (CollectionUtils.isEmpty(userIds) || !userIds.contains(tokenUser.getUserId())) {
            ChannelDO channelDO = channelService.selectByUserIdAndSite(tokenUser.getUserId(), tokenUser.getSiteId());
            if (channelDO != null) {
//                List<PermissionDO> xcxAdminPermissions = permissionProviderService.getPermissionList(XCX_ADMIN_SUBJECT_TYPE);
                List<String> list = new ArrayList<>();
                list.add("renyuanluru");
                list.add("kaoqinjilu");
                list.add("renyuanyudengji");
                list.add("canbaofangan");
                list.add("canbaojilu");
                list.add("gongjiaguize");
                list.add("zhaogonglaowufeiguize");
                List<PermissionDO> xcxAdminPermissions = permissionProviderService.getPermissionListByEnName(list);
                List<String> pmsStringList = allPermissionVO.getPermissionStringList();
                if (CollectionUtils.isEmpty(pmsStringList)) {
                    allPermissionVO.setPermissionStringList(permissionProviderService.getPermissionStringList(xcxAdminPermissions));
                }else {
                    pmsStringList.addAll(permissionProviderService.getPermissionStringList(xcxAdminPermissions));
                }
            }
        }

        //校验菜单和原子权限串 是否在租户范围内
        filterSitePermission(allPermissionVO, tokenUser.getSiteId());
        return allPermissionVO;
    }

    @Override
    public AllPermissionVO listUserPermissionForApp(String companyId, TokenUser tokenUser) {

        AllPermissionVO allPermissionVO = listUserPermission(companyId, tokenUser);

        // 小程序登录使用 查询站点需要有员工
        List<EmpInfoDO> empInfoDOList = empInfoService.listByUserIdNotSiteId(tokenUser.getUserId());
        if (CollectionUtils.isEmpty(empInfoDOList)) {
            allPermissionVO.setSiteList(new ArrayList<>());
        } else {
            // 有员工的站点
            List<String> empSiteIds = empInfoDOList.parallelStream().map(BaseDO::getSiteId).distinct().collect(Collectors.toList());
            allPermissionVO.setSiteList(allPermissionVO.getSiteList().parallelStream().filter(siteVO
                    -> empSiteIds.contains(siteVO.getId())).collect(Collectors.toList()));
        }
        return allPermissionVO;
    }

    /**
     * 菜单和原子权限串 是否在租户范围内
     *
     * @param allPermissionVO 用户权限
     * @param siteId          站点Id
     */
    private void filterSitePermission(AllPermissionVO allPermissionVO, String siteId) {
        //权限字符串
        List<String> permissionStringList = allPermissionVO.getPermissionStringList();
        if (CollectionUtils.isEmpty(permissionStringList)) {
            return;
        }

        //租户的权限字符串
        Example example = new Example(RightDO.class);
        example.and().andEqualTo("subjectType", AdminPermissionConstants.SUBJECT_TYPE_HR)
                .andEqualTo("subjectId", PermissionConstants.DEFAULT_SUBJECT_ID)
                .andEqualTo("oprType", AminRightOprTypeEnum.SITE.getValue())
                .andEqualTo("oprId", siteId);
        List<RightDO> rightList = rightDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(rightList)) {
            return;
        }
        String rightValue = PermissionKit.mergeRightValue(rightList);
        List<PermissionDO> sitePermissionList = permissionProviderService.getHasRightPermissionListByRightValue(rightValue);
        List<String> sitePermissionStringList = permissionProviderService.getPermissionStringList(sitePermissionList);

        permissionStringList.retainAll(sitePermissionStringList);

        //根据权限字符串查询菜单集合
        List<MenuVO> menuList = adminProviderService.listByPermissionStr(permissionStringList);
        allPermissionVO.setPermissionStringList(permissionStringList);
        allPermissionVO.setMenuList(menuList);
    }

}
